package com.zzl.alligator.management.monitor.controller;

import com.zzl.alligator.common.constant.Constants;
import com.zzl.alligator.common.util.StringUtils;
import com.zzl.alligator.framework.base.controller.BaseController;
import com.zzl.alligator.framework.cache.ICache;
import com.zzl.alligator.framework.cache.support.CacheSpecEnum;
import com.zzl.alligator.framework.security.LoginUser;
import com.zzl.alligator.framework.support.web.vo.JsonResult;
import com.zzl.alligator.management.monitor.domain.OnlineUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * 在线用户控制器
 *
 * @author zhouziliang
 * @since 2020/7/9
 */
@RestController
@RequestMapping("/monitor/online")
@Slf4j
public class OnlineUserController extends BaseController {

    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private ICache globalCache;

    /**
     * 获取当前在线用户列表
     *
     * @param ipaddr   ip
     * @param userName 用户名
     * @return 在线用户列表
     */
    @GetMapping
    @PreAuthorize("@ss.hasPermi('monitor:online:query')")
    public JsonResult onlineUser(String ipaddr, String userName) {
        Cache cache = cacheManager.getCache(CacheSpecEnum.LOGIN_USER.name());
        com.github.benmanes.caffeine.cache.Cache nativeCache
                = (com.github.benmanes.caffeine.cache.Cache) cache.getNativeCache();
        // 获取所有用户
        ConcurrentMap concurrentMap = nativeCache.asMap();
        Collection<LoginUser> users = concurrentMap.values();
        if (users == null) {
            log.error("用户列表为空？");
            return JsonResult.success();
        }
        List<OnlineUser> onlineUsers = users.stream().filter(user -> {
            boolean ipAddrNotBlank = StringUtils.isNotBlank(ipaddr);
            boolean userNameNotBlank = StringUtils.isNotBlank(userName);
            if (ipAddrNotBlank && userNameNotBlank) {
                return ipaddr.equals(user.getIpaddr()) && userName.equals(user.getUsername());
            }
            if (ipAddrNotBlank) {
                return ipaddr.equals(user.getIpaddr());
            }
            if (userNameNotBlank) {
                return userName.equals(user.getUsername());
            }
            return true;
        }).map(user -> {
            OnlineUser onlineUser = new OnlineUser();
            onlineUser.setBrowser(user.getBrowser());
            if (user.getUser().getDept() != null) {
                onlineUser.setDeptName(user.getUser().getDept().getDeptName());
            }
            onlineUser.setIpaddr(user.getIpaddr());
            onlineUser.setLoginLocation(user.getLoginLocation());
            onlineUser.setLoginTime(user.getLoginTime());
            onlineUser.setOs(user.getOs());
            onlineUser.setTokenId(user.getToken());
            onlineUser.setUserName(user.getUsername());
            return onlineUser;
        }).collect(Collectors.toList());

        return JsonResult.success(getDataTable(onlineUsers));
    }

    /**
     * 踢出用户
     *
     * @param tokenId
     * @return
     */
    @DeleteMapping("/{tokenId}")
    @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
    public JsonResult forceLogout(@PathVariable String tokenId) {
        globalCache.deleteObject(CacheSpecEnum.LOGIN_USER, Constants.LOGIN_TOKEN_KEY + tokenId);
        return JsonResult.success();
    }

    @DeleteMapping
    @PreAuthorize("@ss.hasPermi('monitor:online:batchLogout')")
    public JsonResult forceBatchLogout() {
        globalCache.clearCache(CacheSpecEnum.LOGIN_USER);
        return JsonResult.success();
    }
}
